//
//  KATBrowser.m
//  KATFramework
//
//  Created by Yi Yu on 2017/6/14.
//  Copyright © 2017年 KatApp. All rights reserved.
//

#import "KATBrowser.h"

#import "KATURIParser.h"


#define BROWSER_SCROLL_NONE 0
#define BROWSER_SCROLL_UP 1
#define BROWSER_SCROLL_DOWN 2




@interface KATBrowser ()

///WebView控件
@property(nonatomic,retain) WKWebView *web;

///警告窗口
@property(nonatomic,retain) KATAlertWindow *alertWindow;

///确认窗口
@property(nonatomic,retain) KATButtonWindow *confirmWindow;

///输入窗口
@property(nonatomic,retain) KATInputWindow *inputWindow;

///进度条
@property(nonatomic,retain) KATProgressBar *progressBar;

///失败刷新区域(透明，需要设置contents属性或添加内容,默认尺寸为0.618宽度正方形，中心位置)
@property(nonatomic,retain) KATSprite *refreshArea;

///浏览器状态
@property(nonatomic,assign) int status;

///页面标题
@property(nonatomic,copy) NSString *pageTitle;

///滚动视图offset
@property(nonatomic,assign) double scrollOffset;

///滚动方向
@property(nonatomic,assign) int scrollDirection;

///加载的URL
@property(nonatomic,copy) NSString *currentURL;


@end




@implementation KATBrowser



//获取实例
+ (instancetype)browserWithFrame:(CGRect)frame
{
    return [self browserWithFrame:frame andWKConfig:nil];
}


//获取实例
+ (instancetype)browserWithFrame:(CGRect)frame andWKConfig:(WKWebViewConfiguration *)config
{
    KATBrowser *browser=[[[self alloc] init] autorelease];
        
    browser.status=BROWSER_STATUS_UNKNOWN;
    browser.clipsToBounds=YES;
    browser.backgroundColor=KCOLOR_CLEAR;
    browser.scrollOffset=0;
    browser.scrollDirection=BROWSER_SCROLL_NONE;
    browser.pageTitle=nil;
    browser.marginTop=0.0;
    browser.marginBottom=0.0;
    browser.marginLeft=0.0;
    browser.marginRight=0.0;
    browser.topInsertHeight=0.0;
    browser.bottomInsertHeight=0.0;
    
    //WebView
    if(config)
    {
        browser.web=[[[WKWebView alloc] initWithFrame:browser.bounds configuration:config] autorelease];
    }
    else
    {
        browser.web=[[[WKWebView alloc] init] autorelease];
        browser.web.frame=browser.bounds;
    }
    
    browser.web.opaque=NO;
    browser.web.backgroundColor=[UIColor clearColor];
    browser.web.allowsBackForwardNavigationGestures=YES;
    [browser addSubview:browser.web];
    
    //代理
    browser.web.navigationDelegate=browser;
    browser.web.UIDelegate=browser;
    browser.eventDelegate=nil;
    
    //弹窗
    browser.alertWindow=[KATAlertWindow windowWithTitle:nil];
    browser.confirmWindow=[KATButtonWindow windowWithTitle:nil titleStyle:nil info:nil infoStyle:nil andButtons:ARRAY([KATButton buttonWithFrame:CGRectZero type:KATButtonTypeClose color:KCOLOR_RED lineWidth:1.5 scale:1.0 andOnClickAction:nil],[KATButton buttonWithFrame:CGRectZero type:KATButtonTypeOK color:KCOLOR_BLUE lineWidth:1.5 scale:1.0 andOnClickAction:nil])];
    browser.inputWindow=[KATInputWindow windowWithTitle:nil];
    
    //schemes
    browser.schemes=ARRAY(@"sms",@"telprompt",@"mailto",@"itms-apps");
    
    //filter
    browser.hostsFilter=nil;
    
    //底部视图
    browser.bottomView=nil;
    
    //进度条
    browser.progressBar=[KATProgressBar progressBarWithFrame:CGRectMake(0, 0, browser.bounds.size.width, 2.0)];
    browser.progressBar.hasRoundCorner=NO;
    browser.progressBar.frontIndent=0;
    browser.progressBar.color=COLOR_BLUE;
    browser.progressBar.bgColorAlpha=0.0;
    [browser.progressBar updateBar];
    
    //进度条监视
    [browser.web addObserver:browser forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
    
    //页面标题监视
    [browser.web addObserver:browser forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil];
    
    //滚动状态监视
    [browser.web.scrollView addObserver:browser forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
    [browser.web.scrollView addObserver:browser forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
    
    
    //加载失败后刷新区域
    browser.refreshArea=[KATSprite sprite];
    browser.refreshArea.bounds=BOUNDS(MIN(frame.size.width,frame.size.height)*0.618, MIN(frame.size.width,frame.size.height)*0.618);
    browser.refreshArea.center=POINT(frame.size.width*0.5, frame.size.height*0.5);
    [browser addSubview:browser.refreshArea];
    
    browser.refreshArea.hidden=YES;
    
    //点击事件
    UITapGestureRecognizer *tap=[[[UITapGestureRecognizer alloc] initWithTarget:browser action:@selector(updateURL)] autorelease];
    [browser.refreshArea addGestureRecognizer:tap];
    
    browser.frame=frame;
    
    return browser;
}


//获取实例
+ (instancetype)browserWithFrame:(CGRect)frame andConfig:(KATBrowserConfig *)config
{
    if(config)
    {
        KATBrowser *browser=[[[self alloc] init] autorelease];
        
        browser.config=config;
        
        browser.status=BROWSER_STATUS_UNKNOWN;
        browser.clipsToBounds=YES;
        browser.backgroundColor=KCOLOR_CLEAR;
        browser.scrollOffset=0;
        browser.scrollDirection=BROWSER_SCROLL_NONE;
        browser.pageTitle=nil;
        browser.marginTop=config.marginTop;
        browser.marginBottom=config.marginBottom;
        browser.marginLeft=config.marginLeft;
        browser.marginRight=config.marginRight;
        browser.topInsertHeight=config.topInsertHeight;
        browser.bottomInsertHeight=config.bottomInsertHeight;
        
        //WebView
        browser.web=[[[WKWebView alloc] initWithFrame:browser.bounds configuration:config.webConfig] autorelease];
        browser.web.opaque=NO;
        browser.web.backgroundColor=[UIColor clearColor];
        browser.web.allowsBackForwardNavigationGestures=YES;
        [browser addSubview:browser.web];
        
        //代理
        browser.web.navigationDelegate=browser;
        browser.web.UIDelegate=browser;
        browser.eventDelegate=nil;
        
        //弹窗
        if(config.alertWindow)
        {
            browser.alertWindow=config.alertWindow;
        }
        else
        {
            browser.alertWindow=[KATAlertWindow windowWithTitle:nil];
        }
        
        if(config.confirmWindow)
        {
            browser.confirmWindow=config.confirmWindow;
        }
        else
        {
            browser.confirmWindow=[KATButtonWindow windowWithTitle:nil titleStyle:nil info:nil infoStyle:nil andButtons:ARRAY([KATButton buttonWithFrame:CGRectZero type:KATButtonTypeClose color:KCOLOR_RED lineWidth:1.5 scale:1.0 andOnClickAction:nil],[KATButton buttonWithFrame:CGRectZero type:KATButtonTypeOK color:KCOLOR_BLUE lineWidth:1.5 scale:1.0 andOnClickAction:nil])];
        }
        
        if(config.inputWindow)
        {
            browser.inputWindow=config.inputWindow;
        }
        else
        {
            browser.inputWindow=[KATInputWindow windowWithTitle:nil];
        }
        
        //schemes
        browser.schemes=config.schemes;
        
        //filter
        browser.hostsFilter=config.hostsFilter;
        
        //底部视图
        browser.bottomView=config.bottomView;
        
        //进度条
        if(config.progressBar)
        {
            browser.progressBar=config.progressBar;
        }
        else
        {
            browser.progressBar=[KATProgressBar progressBarWithFrame:CGRectMake(0, 0, browser.bounds.size.width, 2.0)];
            browser.progressBar.hasRoundCorner=NO;
            browser.progressBar.frontIndent=0;
            browser.progressBar.color=COLOR_BLUE;
            browser.progressBar.bgColorAlpha=0.0;
            [browser.progressBar updateBar];
        }
        
        //进度条监视
        [browser.web addObserver:browser forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
        
        //页面标题监视
        [browser.web addObserver:browser forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil];
        
        //滚动状态监视
        [browser.web.scrollView addObserver:browser forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
        [browser.web.scrollView addObserver:browser forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
        
        
        //加载失败后刷新区域
        browser.refreshArea=[KATSprite sprite];
        browser.refreshArea.bounds=BOUNDS(MIN(frame.size.width,frame.size.height)*0.618, MIN(frame.size.width,frame.size.height)*0.618);
        browser.refreshArea.center=POINT(frame.size.width*0.5, frame.size.height*0.5);
        [browser addSubview:browser.refreshArea];
        
        browser.refreshArea.hidden=YES;
        
        //点击事件
        UITapGestureRecognizer *tap=[[[UITapGestureRecognizer alloc] initWithTarget:browser action:@selector(updateURL)] autorelease];
        [browser.refreshArea addGestureRecognizer:tap];
        
        
        browser.frame=frame;
        
        return browser;
    }
    else
    {
        return [self browserWithFrame:frame];
    }
}


//清空缓存
+ (void)clearCache
{
    //清除WebView的缓存
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
}


//清空cookie
+ (void)clearCookies
{
    //清除cookies
    NSHTTPCookie *cookie;
    
    NSHTTPCookieStorage *storage=[NSHTTPCookieStorage sharedHTTPCookieStorage];
    
    for(cookie in [storage cookies])
    {
        [storage deleteCookie:cookie];
    }
}



- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    
    if(_web)
    {
        _web.frame=RECT(_marginLeft, _marginTop, self.bounds.size.width-_marginLeft-_marginRight, self.bounds.size.height-_marginTop-_marginBottom);
    }
    
    if(_progressBar)
    {
        _progressBar.frame=CGRectMake(0, _marginTop+_topInsertHeight, self.bounds.size.width, _progressBar.bounds.size.height);
    }
}


- (void)setMarginTop:(double)marginTop
{
    _marginTop=marginTop;
    
    self.frame=self.frame;
}


- (void)setMarginBottom:(double)marginBottom
{
    _marginBottom=marginBottom;
    
    self.frame=self.frame;
}


- (void)setMarginLeft:(double)marginLeft
{
    _marginLeft=marginLeft;
    
    self.frame=self.frame;
}


- (void)setMarginRight:(double)marginRight
{
    _marginRight=marginRight;
    
    self.frame=self.frame;
}


- (void)setTopInsertHeight:(double)topInsertHeight
{
    _topInsertHeight=topInsertHeight;
    
    _web.scrollView.contentInset=UIEdgeInsetsMake(_topInsertHeight, 0, _bottomInsertHeight, 0);
    
    _progressBar.frame=RECT(_progressBar.frame.origin.x, _marginTop+_topInsertHeight, _progressBar.bounds.size.width, _progressBar.bounds.size.height);
}


- (void)setBottomInsertHeight:(double)bottomInsertHeight
{
    _bottomInsertHeight=bottomInsertHeight;
    
    _web.scrollView.contentInset=UIEdgeInsetsMake(_topInsertHeight, 0, _bottomInsertHeight, 0);
}


//设置底部视图
- (void)setBottomView:(UIView *)bottomView
{
    if(bottomView!=_bottomView)
    {
        if(_bottomView)
        {
            [_bottomView removeFromSuperview];
            [_bottomView release];
        }
        
        _bottomView=[bottomView retain];
        
        if(_bottomView)
        {
            //添加到底部
            _bottomView.frame=RECT(0, _web.scrollView.contentSize.height, _web.scrollView.bounds.size.width, _bottomView.bounds.size.height);
            [_web.scrollView addSubview:_bottomView];
            
            self.bottomInsertHeight=_bottomView.bounds.size.height;
        }
        else
        {
            self.bottomInsertHeight=0;
        }
    }
}


//重新加载
- (void)reload
{
    if(_web.loading)
    {
        [_web stopLoading];
    }
    
    [_web reload];
}


//刷新(加载最近加载的URL)
- (void)updateURL
{
    if(_web.loading)
    {
        [_web stopLoading];
    }
    
    [self loadURL:_currentURL];
}


//重新加载(优先加载缓存)
- (void)reloadFromOrigin
{
    if(_web.loading)
    {
        [_web stopLoading];
    }
    
    [_web reloadFromOrigin];
}


//回退
- (void)goBack
{
    if(_web.canGoBack)
    {
        [_web goBack];
    }
}


//前进
- (void)goForward
{
    if(_web.canGoForward)
    {
        [_web goForward];
    }
}


//是否能后退
- (BOOL)canGoBack
{
    return _web.canGoBack;
}


//是否能前进
- (BOOL)canGoForward
{
    return _web.canGoForward;
}


//停止加载
- (void)stopLoading
{
    [_web stopLoading];
}


//加载页面
- (void)loadURL:(NSString *)url
{
    self.currentURL=url;
    
    NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
    
    [_web loadRequest:request];
}


//加载空白页
- (void)loadBlank
{
    [self loadURL:@"about:blank"];
}


//加载文件
- (void)loadFile:(NSString *)path
{
    NSURL *url=[NSURL fileURLWithPath:path];
        
    [_web loadFileURL:url allowingReadAccessToURL:url];
}


//加载HTML字符串，baseURL是针对不完整的路径
- (void)loadHTML:(NSString *)html withBaseURL:(NSString *)base
{
    if(html)
    {
        NSURL *url=nil;
        
        if(base)
        {
            url=[NSURL URLWithString:base];
        }
        
        [_web loadHTMLString:html baseURL:url];
    }
}


//加载HTML字符串
- (void)loadHTML:(NSString *)html
{
    [self loadHTML:html withBaseURL:nil];
}


//适应尺寸
- (void)sizeToFit
{
    [_web sizeToFit];
}


//获取当前的url
- (NSString *)currentURL
{
    return [_web.URL absoluteString];
}


//退回到最初的历史记录
- (void)goBackToFirstPage
{
    [self loadBlank];
    WKBackForwardListItem *item=[_web.backForwardList.backList firstObject];
    
    if(item)
    {
        [_web goToBackForwardListItem:item];
    }
}


#pragma -mark JS交互

//执行JS代码
- (void)evalJavaScript:(NSString *)js completion:(void (^)(id obj, NSError *error))completion
{
    if(js)
    {
        [_web evaluateJavaScript:js completionHandler:completion];

    }
}


//通过id获取页面元素的某个属性
- (void)getAtrribute:(NSString *)attr inDocumentWithID:(NSString *)ID completion:(void (^)(id obj,NSError *error))completion
{
    if(attr && ID && completion)
    {
        [self evalJavaScript:[NSString stringWithFormat:@"document.getElementById(\"%@\").%@",ID,attr] completion:completion];
    }
}


//通过id获取页面元素的文本内容
- (void)getTextInDocumentWithID:(NSString *)ID completion:(void (^)(NSString *text,NSError *error))completion
{
    if(ID && completion)
    {
        [self getAtrribute:@"innerHTML" inDocumentWithID:ID completion:^(id obj, NSError *error)
        {
            if(completion)//强迫症，再判断一次
            {
                completion((NSString *)obj,error);
            }
        }];
    }
}


//获取页面中所有的图片(map类型，包含src、id、name、alt)
- (void)getImagesInDocumentWithCompletion:(void (^)(KATArray<KATHashMap *> *images,NSError *error))completion
{
    [self evalJavaScript:@"function _KATBrowserGetImages()\
    {\
        var arrSep='*&kat_array_sep&*';\
        var mapSep='*&kat_map_sep&*';\
        var mapOpt='*&kat_map_opt&*';\
     \
        var objs=document.getElementsByTagName(\"img\");\
     \
        var result='';\
     \
        for(var i=0;i<objs.length;i++)\
        {\
            if(objs[i].src)\
            {\
                result+=\"src\"+mapOpt+objs[i].src+mapSep;\
            }\
     \
            if(objs[i].alt)\
            {\
                result+=\"alt\"+mapOpt+objs[i].alt+mapSep;\
            }\
     \
            if(objs[i].id)\
            {\
                result+=\"id\"+mapOpt+objs[i].id+mapSep;\
            }\
     \
            if(objs[i].name)\
            {\
                result+=\"name\"+mapOpt+objs[i].name+mapSep;\
            }\
     \
            result+=arrSep;\
        };\
     \
        return result;\
    };\
    \
    _KATBrowserGetImages();"
    completion:^(id obj, NSError *error)
    {
        //返回的数组
        KATArray<KATHashMap *> *array=[KATArray array];
        
        //原始字符串数组
        KATArray *stringArray=[KATArray arrayWithString:obj andSep:@"*&kat_array_sep&*"];
        
        for(NSString *string in stringArray)
        {
            KATHashMap *map=[KATHashMap hashMapWithString:string andSep:@"*&kat_map_sep&*" andOpt:@"*&kat_map_opt&*"];
            
            [array put:map];
        }
        
        if(completion)
        {
            completion(array,error);
        }
    }];
}


//在底部插入空白
- (void)insertBottomWithHeight:(double)height
{
    [self evalJavaScript:[NSString stringWithFormat:@"\
                          var div=document.createElement(\"div\");\
                          div.style.width=document.body.clientWidth;\
                          div.style.height=\"%.1lfpx\";\
                          document.body.appendChild(div);",
                          height] completion:nil];
}


//在顶部插入空白
- (void)insertTopWithHeight:(double)height
{
    [self evalJavaScript:[NSString stringWithFormat:@"\
                          var div=document.createElement(\"div\");\
                          div.style.width=document.body.clientWidth;\
                          div.style.height=\"%.1lfpx\";\
                          var first=document.body.firstChild;\
                          document.body.insertBefore(div,first);",
                          height] completion:nil];
}



#pragma -mark WKNavigation代理

//(2)页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    _status=BROWSER_STATUS_START;
    
    [KATAppUtil setNetworkStateActive:YES];//显示状态栏的网络活动指示器
    
    //初始化滚动状态
    _scrollOffset=0;
    _scrollDirection=BROWSER_SCROLL_NONE;
    
    //失败刷新区域
    _refreshArea.hidden=YES;
    
    [_progressBar progressWithValue:0.0 animated:NO];
    [self addSubview:_progressBar];
    
    if(_eventDelegate && [_eventDelegate respondsToSelector:@selector(browserDidStartLoading:)])
    {
        [_eventDelegate browserDidStartLoading:self];
    }
}


//(4)当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
{
    _status=BROWSER_STATUS_COMMIT;
    
    if(_eventDelegate && [_eventDelegate respondsToSelector:@selector(browserDidCommitLoading:)])
    {
        [_eventDelegate browserDidCommitLoading:self];
    }
}


//(5)页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    _status=BROWSER_STATUS_FINISH;
    
    [KATAppUtil setNetworkStateActive:NO];//关闭状态栏的网络活动指示器
    
    //失败刷新区域
    _refreshArea.hidden=YES;
    
    [_progressBar removeFromSuperview];
    
//    if(_topInsertHeight>0)//顶部插入
//    {
//        [self insertTopWithHeight:_topInsertHeight];
//    }
//    
//    if(_bottomInsertHeight>0)//底部插入
//    {
//        [self insertBottomWithHeight:_bottomInsertHeight];
//    }
    
    if(_eventDelegate && [_eventDelegate respondsToSelector:@selector(browserDidFinishLoading:)])
    {
        [_eventDelegate browserDidFinishLoading:self];
    }
}


//页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error;
{
    _status=BROWSER_STATUS_FAIL;
    
    [KATAppUtil setNetworkStateActive:NO];//关闭状态栏的网络活动指示器
    
    //失败刷新区域
    _refreshArea.hidden=NO;
    
    [_progressBar removeFromSuperview];
    
    if(_eventDelegate && [_eventDelegate respondsToSelector:@selector(browserDidFailLoading:)])
    {
        [_eventDelegate browserDidFailLoading:self];
    }
}


//接收到服务器跳转请求之后调用(服务器端redirect)，不一定调用
//- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
//{
//    
//}


//(1)在发送请求之前，决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    //URL解析
    NSString *url=[navigationAction.request.URL absoluteString];
    NSString *scheme=[KATURIParser parseURI:url][kURIKeyScheme];
    NSString *host=[KATURIParser parseURI:url][kURIKeyHost];
    
    //默认允许跳转
    WKNavigationActionPolicy policy=WKNavigationActionPolicyAllow;
    BOOL decision=YES;
    
    if(scheme && _schemes && _schemes.length>0)
    {
        if([[KATAppUtil schemes] hasMember:scheme])//内部路由 
        {
            decision=NO;
            
            [KATRouter routeWithURI:url];
        }
        else if([_schemes hasMember:scheme])//跳转
        {
            decision=NO;
            
            //防止iOS 10及其之后，拨打电话系统弹出框延迟出现
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
            {
                GCD_SYNC_MAIN(
                {
                    [[UIApplication sharedApplication] openURL:navigationAction.request.URL];
                });
            });
        }
    }
    
    if(_hostsFilter)//存在过滤器
    {
        if([_hostsFilter hasMember:host])
        {
            decision=YES;
        }
        else
        {
            decision=NO;
        }
    }
    
    if(_eventDelegate && [_eventDelegate respondsToSelector:@selector(browser:shouldLoadWithRequest:)])
    {
        decision=[_eventDelegate browser:self shouldLoadWithRequest:navigationAction.request];
    }
    
    if(!decision)
    {
        policy=WKNavigationActionPolicyCancel;
    }
    else
    {
        self.currentURL=url;
    }
    
    if(decisionHandler)
    {
        decisionHandler(policy);
    }
}


//(3)在收到服务器的响应头，根据response相关信息，决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    //默认允许跳转
    WKNavigationResponsePolicy policy=WKNavigationResponsePolicyAllow;
    BOOL decision=YES;
    
    if(_eventDelegate && [_eventDelegate respondsToSelector:@selector(browser:shouldLoadWithResponse:)])
    {
        decision=[_eventDelegate browser:self shouldLoadWithResponse:navigationResponse.response];
    }
    
    if(!decision)
    {
        policy=WKNavigationResponsePolicyCancel;
    }

    if(decisionHandler)
    {
        decisionHandler(policy);
    }
}


//身份验证
//- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler
//{
//    
//}


//导航错误
//- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
//{
//    
//}


//终止
//- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
//{
//    
//}




#pragma -mark WKUIDelegate代理

//打开新窗口(新建一个webView) open()方法
//- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
//{
//
//}


//输入框 prompt()方法
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler
{
    //当前VC
    if([KATAppUtil controllerWithView:self]==[KATAppUtil topViewController])
    {
        _inputWindow.title=prompt;
        
        _inputWindow.onConfirmAction=^(NSString *text)
        {
            if(completionHandler)
            {
                completionHandler(_inputWindow.textField.text);
            }
        };
        
        _inputWindow.cancelButton.onClickAction=^
        {
            if(completionHandler)
            {
                completionHandler(nil);
            }
        };
        
        [_inputWindow show];
    }
    else
    {
        if(completionHandler)
        {
            completionHandler(nil);
        }
    }
}



//确认框 confirm()方法
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
{
    //当前VC
    if([KATAppUtil controllerWithView:self]==[KATAppUtil topViewController])
    {
        _confirmWindow.title=message;
        
        ((KATButton *)[_confirmWindow.buttons firstMember]).onClickAction=^
        {
            if(completionHandler)
            {
                completionHandler(NO);
            }
            
            [_confirmWindow hide];
        };
        
        ((KATButton *)[_confirmWindow.buttons lastMember]).onClickAction=^
        {
            if(completionHandler)
            {
                completionHandler(YES);
            }
            
            [_confirmWindow hide];
        };
        
        [_confirmWindow show];
    }
    else
    {
        if(completionHandler)
        {
            completionHandler(NO);
        }
    }
}


//警告框 alert()方法
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
    //当前VC
    if([KATAppUtil controllerWithView:self]==[KATAppUtil topViewController])
    {
        _alertWindow.title=message;
        [_alertWindow show];
        
        if(completionHandler)
        {
            completionHandler();
        }
    }
    else
    {
        if(completionHandler)
        {
            completionHandler();
        }
    }
}


#pragma mark - KVO

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    if([@"estimatedProgress" isEqualToString:keyPath])//进度条
    {
        [_progressBar progressWithValue:_web.estimatedProgress animated:YES];
        
        if(_web.estimatedProgress>=1.0)
        {
            _status=BROWSER_STATUS_FINISH;
            
            //0.5秒后隐藏
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
            {
                // 再次判断，防止正在加载时隐藏
                if(_progressBar.rightValue>=1.0)
                {
                    [_progressBar removeFromSuperview];
                }
            });
        }
    }
    else if([@"title" isEqualToString:keyPath])//标题
    {
        self.pageTitle=_web.title;
        
        if(_pageTitle && _pageTitle.length>0)//加载时会在开始的阶段变为空值
        {
            //回调
            if(_eventDelegate && [_eventDelegate respondsToSelector:@selector(browserDidChangePageTitle:)])
            {
                [_eventDelegate browserDidChangePageTitle:self];
            }
        }
    }
    else if([@"contentOffset" isEqualToString:keyPath])//滚动视图
    {
        double offset=_web.scrollView.contentOffset.y;
        
        if(offset-4.0>_scrollOffset)//向下滚动
        {
            if(_scrollDirection!=BROWSER_SCROLL_DOWN)//状态发生改变
            {
                //回调
                if(_status==BROWSER_STATUS_FINISH && _eventDelegate && [_eventDelegate respondsToSelector:@selector(browserDidScrollDown:)])
                {
                    [_eventDelegate browserDidScrollDown:self];
                }
            }
            
            _scrollDirection=BROWSER_SCROLL_DOWN;
        }
        else if(offset+4.0<_scrollOffset)//向上滚动
        {
            if(_scrollDirection!=BROWSER_SCROLL_UP)//状态发生改变
            {
                //回调
                if(_status==BROWSER_STATUS_FINISH && _eventDelegate && [_eventDelegate respondsToSelector:@selector(browserDidScrollUp:)])
                {
                    [_eventDelegate browserDidScrollUp:self];
                }
            }
            
            _scrollDirection=BROWSER_SCROLL_UP;
        }
        
        _scrollOffset=offset;
    }
    else if([@"contentSize" isEqualToString:keyPath])//页面内容大小发生变化
    {
        if(_bottomView.frame.origin.y!=_web.scrollView.contentSize.height)
        {
            if(_bottomView)
            {
                //位置调整
                _bottomView.frame=RECT(0, _web.scrollView.contentSize.height, _web.scrollView.bounds.size.width, _bottomView.bounds.size.height);
            }
        }
    }
}




- (void)dealloc
{
    //取消监听
    if(_web)
    {
        @try
        {
            [_web removeObserver:self forKeyPath:@"estimatedProgress"];
            [_web removeObserver:self forKeyPath:@"title"];
            [_web.scrollView removeObserver:self forKeyPath:@"contentOffset"];
            [_web.scrollView removeObserver:self forKeyPath:@"contentSize"];
        }
        @catch(NSException *exception)
        {
            NSLog(@"<Exception> %@ : %@",self,exception);
        } 
    }
    
    [KATAppUtil setNetworkStateActive:NO];//关闭状态栏的网络活动指示器
    
    [_web release];
    [_alertWindow release];
    [_confirmWindow release];
    [_inputWindow release];
    [_bottomView release];
    [_schemes release];
    [_hostsFilter release];
    [_progressBar release];
    [_refreshArea release];
    [_pageTitle release];
    [_currentURL release];
    [_config release];
    
    [super dealloc];
}



@end



